package org.grapes.wine.api.server.method;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.grapes.wine.api.method.EWineMethod;
import org.grapes.wine.api.server.core.ReadData;
import org.grapes.wine.api.server.exception.MethodErrorCode;
import org.grapes.wine.api.server.exception.MethodException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

public abstract class MethodHandler implements MethodCommand {
	private DocumentBuilderFactory documentBuilderFactory;
	private Document doc = null;
	
	public Document init(HttpServletRequest request, List param,
			int methodErrorCode, int methodParameterNotMatch) {
		documentBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = null;
		try {
			docBuilder = documentBuilderFactory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			try {
				throw new ServletException(
						"unable to create DocumentBuilderFactory", e);
			} catch (ServletException e1) {
				e1.printStackTrace();
			}
		}
		
		doc = docBuilder.newDocument();
		try {
			String method = request.getParameter("method");
			System.out.println("method"+method);
			if (method == null) {
				System.out.println("here?");
				throw new MethodException(MethodErrorCode.METHOD_NOT_FOUND);
			}
			if (!EWineMethod.GET_USER.methodName().equals(method))
				throw new MethodException(methodErrorCode);
				
			Iterator it = param.iterator();
			while (it.hasNext()) {
				String p = (String) it.next();
				String p2 = request.getParameter(p);
				if (p2 == null)
					throw new MethodException(methodParameterNotMatch);
			}
			
			doc = renderDocument();
		} catch (MethodException we) {
			doc = we.getDocument();
		}
		return doc;
	}
	
	private Document renderDocument() {
		try {
			ReadData rd = new ReadData();
			List userList;
			userList = rd.readTable();

			// create the DOM document
			Element wineResponse = doc.createElement("wineResponse");
			doc.appendChild(wineResponse);
			Element users = doc.createElement("users");
			wineResponse.appendChild(users);
			for (Iterator it = userList.iterator(); it.hasNext();) {
				Map userMap = (Map) it.next();
				Element user = doc.createElement("user");
				users.appendChild(user);
				user.appendChild(newElementFromMap(userMap, "userId", doc));
				user.appendChild(newElementFromMap(userMap, "name", doc));
				user.appendChild(newElementFromMap(userMap, "email", doc));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return doc;
	}
	
	private Element newElementFromMap(Map map, String key, Document doc) {
		String text = (String) map.get(key);
		Text textNode = doc.createTextNode(text);
		Element element = doc.createElement(key);
		element.appendChild(textNode);
		return element;
	}
}
